package com.ruoyi.business.service.impl;

import com.ruoyi.business.constant.IBusinessConstant;
import com.ruoyi.business.domain.TenantFunctionComposite;
import com.ruoyi.business.domain.TenantFunctionMain;
import com.ruoyi.business.domain.TenantFunctionParametersVersion;
import com.ruoyi.business.domain.TenantFunctionVersion;
import com.ruoyi.business.mapper.TenantFunctionMainMapper;
import com.ruoyi.business.service.ITenantFunctionMainService;
import com.ruoyi.business.service.ITenantFunctionParametersVersionService;
import com.ruoyi.business.service.ITenantFunctionVersionService;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.UniqueIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 租户组件功能点主表Service业务层处理
 *
 * @author ruoyi
 * @date 2025-04-18
 */
@Service
public class TenantFunctionMainServiceImpl implements ITenantFunctionMainService
{
    @Autowired
    private TenantFunctionMainMapper tenantFunctionMainMapper;
    @Autowired
    private ITenantFunctionVersionService tenantFunctionVersionService;
    @Autowired
    private ITenantFunctionParametersVersionService tenantFunctionParametersVersionService;
    /**
     * 查询租户组件功能点主表
     *
     * @param id 租户组件功能点主表主键
     * @return 租户组件功能点主表
     */
    @Override
    public TenantFunctionMain selectTenantFunctionMainById(Long id)
    {
        return tenantFunctionMainMapper.selectTenantFunctionMainById(id);
    }

    /**
     * 查询租户组件功能点主表列表(排除逻辑删除的）
     *
     * @param tenantFunctionMain 租户组件功能点主表
     * @return 租户组件功能点主表
     */
    @Override
    public List<TenantFunctionMain> selectTenantFunctionMainList(TenantFunctionMain tenantFunctionMain)
    {
        return tenantFunctionMainMapper.selectTenantFunctionMainList(tenantFunctionMain);
    }

    /**
     * 新增租户组件功能点主表
     *
     * @param tenantFunctionMain 租户组件功能点主表
     * @return 结果
     */
    @Override
    public int insertTenantFunctionMain(TenantFunctionMain tenantFunctionMain)
    {
        tenantFunctionMain.setCreateTime(DateUtils.getNowDate());
        //自动产生组件功能编码，并保证唯一
        String functionCode;
        TenantFunctionMain searchTenantFunction = new TenantFunctionMain();
        while (true) {
            functionCode = UniqueIdGenerator.getUniqueClassName(10);
            searchTenantFunction.setFunctionCode(functionCode);
            List<TenantFunctionMain> list = tenantFunctionMainMapper.selectTenantFunctionMainList(searchTenantFunction);
            if (list.size() == 0) {
                tenantFunctionMain.setFunctionCode(functionCode);
                 break;
            }
        }
        return tenantFunctionMainMapper.insertTenantFunctionMain(tenantFunctionMain);
    }

    /**
     * 修改租户组件功能点主表
     *
     * @param tenantFunctionMain 租户组件功能点主表
     * @return 结果
     */
    @Override
    public int updateTenantFunctionMain(TenantFunctionMain tenantFunctionMain)
    {
        tenantFunctionMain.setUpdateTime(DateUtils.getNowDate());
        return tenantFunctionMainMapper.updateTenantFunctionMain(tenantFunctionMain);
    }

    /**
     * 批量删除租户组件功能点主表
     *
     * @param ids 需要删除的租户组件功能点主表主键
     * @return 结果
     */
    @Override
    public int deleteTenantFunctionMainByIds(Long[] ids)
    {
        int sum =0;
        for(Long id:ids) {
            sum += deleteTenantFunctionMainById(id);
        }
        return sum;
    }

    /**
     * 逻辑删除租户组件功能点主表信息
     *
     * @param id 租户组件功能点主表主键
     * @return 结果
     */
    @Override
    public int deleteTenantFunctionMainById(Long id)
    {
        TenantFunctionMain vo = tenantFunctionMainMapper.selectTenantFunctionMainById(id);
        if (vo==null)
            throw new ServiceException("数据不存在");
        if(!vo.getStatus().equals(IBusinessConstant.STATUS_DELETE)){
            vo.setStatus(IBusinessConstant.STATUS_DELETE);
            vo.setUpdateBy(SecurityContextHolder.getUserName());
            vo.setUpdateTime(DateUtils.getNowDate());
            return tenantFunctionMainMapper.updateTenantFunctionMain(vo);
        }
        return 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long commitInsertTenantFunctionMain(TenantFunctionComposite tenantFunctionComposite) {
        //校验基本信息
        verifyInsertTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
        //校验功能点信息
        verifyInsertTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
        //校验功能点参数信息
        verifyInsertTenantFunctionParametersVersion(tenantFunctionComposite.getTenantFunctionParametersVersions());
        //填充默认值
        fillInsertDefaultValues(tenantFunctionComposite);
        //插入基本信息
        tenantFunctionMainMapper.insertTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
        //生成groovy脚本
        tenantFunctionComposite.getTenantFunctionVersion().setGroovySource(tenantFunctionVersionService.makeGroovySource(tenantFunctionComposite));
        //插入功能点信息
        tenantFunctionVersionService.insertTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
        //插入功能点参数信息
        for(TenantFunctionParametersVersion tenantFunctionParametersVersion:tenantFunctionComposite.getTenantFunctionParametersVersions()){
            tenantFunctionParametersVersionService.insertTenantFunctionParametersVersion(tenantFunctionParametersVersion);
        }
        return tenantFunctionComposite.getTenantFunctionMain().getFunctionId();
    }

    /**
     * 插时默认值设置:版本号，当前版本，是否当前版本，企业编码
     * @param tenantFunctionComposite
     */
    private void fillInsertDefaultValues(TenantFunctionComposite tenantFunctionComposite) {
        //基本信息
        tenantFunctionComposite.getTenantFunctionMain().setVersion(1);
        tenantFunctionComposite.getTenantFunctionMain().setEnterpriseCode(SecurityContextHolder.getEnterpriseCode());
        //设置状态为已提交
        tenantFunctionComposite.getTenantFunctionMain().setStatus(IBusinessConstant.STATUS_SUBMIT);
        tenantFunctionComposite.getTenantFunctionMain().setCreateBy(SecurityContextHolder.getUserName());
        tenantFunctionComposite.getTenantFunctionMain().setCreateTime(DateUtils.getNowDate());
        tenantFunctionComposite.getTenantFunctionMain().setFunctionCode(getNewFunctionCode());
        //版本表信息
        tenantFunctionComposite.getTenantFunctionVersion().setVersion(1);
        tenantFunctionComposite.getTenantFunctionVersion().setIsCurrent("Y");
        tenantFunctionComposite.getTenantFunctionVersion().setEnterpriseCode(SecurityContextHolder.getEnterpriseCode());
        tenantFunctionComposite.getTenantFunctionVersion().setCreateBy(SecurityContextHolder.getUserName());
        tenantFunctionComposite.getTenantFunctionVersion().setCreateTime(DateUtils.getNowDate());
        tenantFunctionComposite.getTenantFunctionVersion().setFunctionCode(tenantFunctionComposite.getTenantFunctionMain().getFunctionCode());
        tenantFunctionComposite.getTenantFunctionVersion().setClassName(tenantFunctionComposite.getTenantFunctionMain().getClassName());
        //参数表信息
        for(TenantFunctionParametersVersion tenantFunctionParametersVersion:tenantFunctionComposite.getTenantFunctionParametersVersions()){
            tenantFunctionParametersVersion.setVersion(1);
            tenantFunctionParametersVersion.setParameterId(null);
            tenantFunctionParametersVersion.setEnterpriseCode(SecurityContextHolder.getEnterpriseCode());
            tenantFunctionParametersVersion.setCreateBy(SecurityContextHolder.getUserName());
            tenantFunctionParametersVersion.setCreateTime(DateUtils.getNowDate());
            tenantFunctionParametersVersion.setFunctionCode(tenantFunctionComposite.getTenantFunctionMain().getFunctionCode());
            tenantFunctionParametersVersion.setIsCurrent("Y");
            tenantFunctionParametersVersion.setParameterCode(getNewParameterCode());
            tenantFunctionParametersVersion.setClassName(tenantFunctionComposite.getTenantFunctionMain().getClassName());
        }
    }

    /**
     * 获取新的参数编码
     * @return
     */
    private String getNewParameterCode() {
        String parameterCode="";
        while (true){
            parameterCode = UniqueIdGenerator.getUniqueClassName(10);
            TenantFunctionParametersVersion searchTenantFunctionParametersVersion = new TenantFunctionParametersVersion();
            searchTenantFunctionParametersVersion.setParameterCode(parameterCode);
            List<TenantFunctionParametersVersion> list = tenantFunctionParametersVersionService.selectTenantFunctionParametersVersionList(searchTenantFunctionParametersVersion);
            if(list.size()==0)
                break;
        }
        return parameterCode;
    }

    /**
     * 获取新功能编码
     * @return
     */
    private String getNewFunctionCode() {
        String functionCode="";
        while (true){
            functionCode = UniqueIdGenerator.getUniqueClassName(10);
            TenantFunctionMain searchTenantFunction = new TenantFunctionMain();
            searchTenantFunction.setFunctionCode(functionCode);
            List<TenantFunctionMain> list = tenantFunctionMainMapper.selectTenantFunctionMainList(searchTenantFunction);
            if(list.size()==0)
                break;
        }
        return functionCode;
    }

    private void verifyInsertTenantFunctionParametersVersion(List<TenantFunctionParametersVersion> tenantFunctionParametersVersions) {
        if(tenantFunctionParametersVersions==null)
            throw new RuntimeException("租户组件功能点参数版本表不能为空");
        int index =0;
        for(TenantFunctionParametersVersion tenantFunctionParametersVersion:tenantFunctionParametersVersions){
            if(tenantFunctionParametersVersion==null)
                throw new RuntimeException("租户组件功能点参数版本表不能为空");
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getParameterName()))
                throw new RuntimeException("租户组件功能点参数版本表参数名称不能为空");
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getParameterType()))
                throw new RuntimeException("租户组件功能点参数版本表参数类型不能为空");
            //参数名称不能重复
            if(isRepeatParameterName(tenantFunctionParametersVersions,tenantFunctionParametersVersion,index))
                throw new RuntimeException("租户组件功能点参数版本表参数名称不能重复");
            index++;
        }
    }

    private void verifyInsertTenantFunctionVersion(TenantFunctionVersion tenantFunctionVersion) {
        if(tenantFunctionVersion==null)
            throw new RuntimeException("租户组件功能点版本表不能为空");
        if(StringUtils.isEmpty(tenantFunctionVersion.getDesignScript()))
            throw new RuntimeException("租户组件功能点版本表设计脚本不能为空");
        if(StringUtils.isEmpty(tenantFunctionVersion.getIsReturnvalue()))
            throw new RuntimeException("租户组件功能点版本表是否返回值不能为空");
        if(!IBusinessConstant.SYSTEM_YES.equals(tenantFunctionVersion.getIsReturnvalue()) &&
                !IBusinessConstant.SYSTEM_NO.equals(tenantFunctionVersion.getIsReturnvalue())
            )
            throw new RuntimeException("租户组件功能点版本表是否返回值只能是Y或者N");
        if(IBusinessConstant.SYSTEM_YES.equals(tenantFunctionVersion.getIsReturnvalue()))
            if(StringUtils.isEmpty(tenantFunctionVersion.getReturnType()))
                throw new RuntimeException("租户组件功能点版本表返回值类型不能为空");
    }

    private void verifyInsertTenantFunctionMain(TenantFunctionMain tenantFunctionMain) {
        if(tenantFunctionMain==null)
            throw new RuntimeException("租户组件功能点主表不能为空");
        if(StringUtils.isEmpty(tenantFunctionMain.getFunctionName()))
            throw new RuntimeException("租户组件功能点主表功能点名称不能为空");
        if(StringUtils.isEmpty(tenantFunctionMain.getClassName()))
            throw new RuntimeException("租户组件功能点主表类名不能为空");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int commitUpdateTenantFunctionMain(TenantFunctionComposite tenantFunctionComposite) {
        //校验基本信息
        verifyUpdateTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
        //校验功能点信息
        verifyUpdateTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
        //校验功能点参数信息
        verifyUpdateTenantFunctionParametersVersion(tenantFunctionComposite.getTenantFunctionParametersVersions(),tenantFunctionComposite);
        //判断主表状态是否为已提交，如果是则版本号+1
        if(IBusinessConstant.STATUS_SUBMIT.equals(tenantFunctionComposite.getTenantFunctionMain().getStatus())) {
            //更新其他版本为非当前版本
//            tenantFunctionComposite.getTenantFunctionVersion().setIsCurrent("N");
//            tenantFunctionVersionService.updateTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
            tenantFunctionVersionService.updateCurrentVersionToIsNot(
                    tenantFunctionComposite.getTenantFunctionMain().getFunctionCode(),
                    tenantFunctionComposite.getTenantFunctionMain().getEnterpriseCode());
            //更新功能参数当前版本标志设置为非当前
            tenantFunctionParametersVersionService.updateCurrentVersionToIsNot(
                    tenantFunctionComposite.getTenantFunctionMain().getFunctionCode(),
                    tenantFunctionComposite.getTenantFunctionMain().getEnterpriseCode());

            //填充版本号：最大版本号+1
            fillUpdateDefaultValues(tenantFunctionComposite);

            //更新基本信息
            if(tenantFunctionComposite.getTenantFunctionMain().getSortNumber()==null){
                tenantFunctionComposite.getTenantFunctionMain().setSortNumber(1);
            }
            tenantFunctionMainMapper.updateTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
            //更新功能点信息
            tenantFunctionComposite.getTenantFunctionVersion().setIsCurrent("Y");
            tenantFunctionComposite.getTenantFunctionVersion().setFunctionId(null);
            //生成groovy脚本
            tenantFunctionComposite.getTenantFunctionVersion().setGroovySource(tenantFunctionVersionService.makeGroovySource(tenantFunctionComposite));
            tenantFunctionVersionService.insertTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
            //删除原来参数，再插入参数
            tenantFunctionParametersVersionService.deleteTenantFunctionParametersVersionByFunctionCode(
                    tenantFunctionComposite.getTenantFunctionMain().getFunctionCode(),
                    tenantFunctionComposite.getTenantFunctionMain().getEnterpriseCode(),
                    tenantFunctionComposite.getTenantFunctionVersion().getVersion()
            );
            //插入当前提交信息为当前版本
            for (TenantFunctionParametersVersion tenantFunctionParametersVersion : tenantFunctionComposite.getTenantFunctionParametersVersions()) {
                //去掉ID,防止主键重复
                tenantFunctionParametersVersion.setParameterId(null);
                tenantFunctionParametersVersionService.insertTenantFunctionParametersVersion(tenantFunctionParametersVersion);
            }
        }else{
            //状态改成已提交
            tenantFunctionComposite.getTenantFunctionMain().setStatus(IBusinessConstant.STATUS_SUBMIT);
            //更新基本信息
            tenantFunctionMainMapper.updateTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
            tenantFunctionComposite.getTenantFunctionVersion().setIsCurrent("Y");
            //生成groovy脚本
            tenantFunctionComposite.getTenantFunctionVersion().setGroovySource(tenantFunctionVersionService.makeGroovySource(tenantFunctionComposite));
            tenantFunctionVersionService.updateTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
            //删除原来参数，再插入参数
            tenantFunctionParametersVersionService.deleteTenantFunctionParametersVersionByFunctionCode(
                    tenantFunctionComposite.getTenantFunctionMain().getFunctionCode(),
                    tenantFunctionComposite.getTenantFunctionMain().getEnterpriseCode(),
                    tenantFunctionComposite.getTenantFunctionVersion().getVersion()
                    );
            for (TenantFunctionParametersVersion tenantFunctionParametersVersion : tenantFunctionComposite.getTenantFunctionParametersVersions()) {
                tenantFunctionParametersVersionService.insertTenantFunctionParametersVersion(tenantFunctionParametersVersion);
            }


        }
        return 1;
    }

    /**
     * 复合模式更新
     *
     * @param tenantFunctionComposite
     * @return
     */
    @Override
    public int updateTenantFunctionComposite(TenantFunctionComposite tenantFunctionComposite) {
        //判断当前主表状态
        //如果是草稿，则更新
        if(IBusinessConstant.STATUS_DRAF.equals(tenantFunctionComposite.getTenantFunctionMain().getStatus())){
            //简单更新即可
            tenantFunctionMainMapper.updateTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
            tenantFunctionVersionService.updateTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
            //删除原来参数，再插入参数
            tenantFunctionParametersVersionService.deleteTenantFunctionParametersVersionByFunctionCode(
                    tenantFunctionComposite.getTenantFunctionMain().getFunctionCode(),
                    tenantFunctionComposite.getTenantFunctionMain().getEnterpriseCode(),
                    tenantFunctionComposite.getTenantFunctionVersion().getVersion()
            );
            for (TenantFunctionParametersVersion tenantFunctionParametersVersion : tenantFunctionComposite.getTenantFunctionParametersVersions()) {
                tenantFunctionParametersVersionService.insertTenantFunctionParametersVersion(tenantFunctionParametersVersion);
            }
        //如果是已提交，则版本号加1,然后更新主表，然后插入功能点版本表及参数表
        }else{
            //版本号+1
            fillUpdateDefaultValues(tenantFunctionComposite);
            //主表状态设置为草稿
            tenantFunctionComposite.getTenantFunctionMain().setStatus(IBusinessConstant.STATUS_DRAF);
            tenantFunctionMainMapper.updateTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
            tenantFunctionComposite.getTenantFunctionVersion().setIsCurrent("N");
            tenantFunctionVersionService.insertTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
            for (TenantFunctionParametersVersion tenantFunctionParametersVersion : tenantFunctionComposite.getTenantFunctionParametersVersions()) {
                tenantFunctionParametersVersionService.insertTenantFunctionParametersVersion(tenantFunctionParametersVersion);
            }
        }
        return 1;
    }

    /**
     * 复合模式插入
     *
     * @param tenantFunctionComposite
     * @return
     */
    @Override
    public Long insertTenantFunctionComposite(TenantFunctionComposite tenantFunctionComposite) {
        fillInsertDefaultValues(tenantFunctionComposite);
        //主表状态设置为草稿
        tenantFunctionComposite.getTenantFunctionMain().setStatus(IBusinessConstant.STATUS_DRAF);
        //插入基本信息
        tenantFunctionComposite.getTenantFunctionVersion().setIsCurrent("N");
        tenantFunctionMainMapper.insertTenantFunctionMain(tenantFunctionComposite.getTenantFunctionMain());
        //插入功能点信息
        tenantFunctionVersionService.insertTenantFunctionVersion(tenantFunctionComposite.getTenantFunctionVersion());
        //插入功能点参数信息
        for(TenantFunctionParametersVersion tenantFunctionParametersVersion:tenantFunctionComposite.getTenantFunctionParametersVersions()){
            tenantFunctionParametersVersionService.insertTenantFunctionParametersVersion(tenantFunctionParametersVersion);
        }
        return tenantFunctionComposite.getTenantFunctionMain().getFunctionId();
    }

    /**
     * 填充更新默认值
     * @param tenantFunctionComposite
     */
    private void fillUpdateDefaultValues(TenantFunctionComposite tenantFunctionComposite) {
        int newVersion = tenantFunctionComposite.getTenantFunctionMain().getVersion()+1;
        //设置状态为提交
        tenantFunctionComposite.getTenantFunctionMain().setStatus(IBusinessConstant.STATUS_SUBMIT);
        tenantFunctionComposite.getTenantFunctionMain().setVersion(newVersion);
        tenantFunctionComposite.getTenantFunctionVersion().setIsCurrent(IBusinessConstant.SYSTEM_YES);
        tenantFunctionComposite.getTenantFunctionVersion().setVersion(newVersion);
        if(StringUtils.isEmpty(tenantFunctionComposite.getTenantFunctionVersion().getEnterpriseCode())){
            tenantFunctionComposite.getTenantFunctionVersion().setEnterpriseCode(tenantFunctionComposite.getTenantFunctionMain().getEnterpriseCode());
        }
        if(StringUtils.isEmpty(tenantFunctionComposite.getTenantFunctionVersion().getClassName())){
            tenantFunctionComposite.getTenantFunctionVersion().setClassName(tenantFunctionComposite.getTenantFunctionMain().getClassName());
        }
        if(StringUtils.isEmpty(tenantFunctionComposite.getTenantFunctionVersion().getFunctionCode())){
            tenantFunctionComposite.getTenantFunctionVersion().setFunctionCode(tenantFunctionComposite.getTenantFunctionMain().getFunctionCode());
        }
        //更新参数列表
        for(TenantFunctionParametersVersion tenantFunctionParametersVersion:tenantFunctionComposite.getTenantFunctionParametersVersions()){
            tenantFunctionParametersVersion.setVersion(newVersion);
            tenantFunctionParametersVersion.setIsCurrent(IBusinessConstant.SYSTEM_YES);
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getClassName())){
                tenantFunctionParametersVersion.setClassName(tenantFunctionComposite.getTenantFunctionMain().getClassName());
            }
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getFunctionCode())){
                tenantFunctionParametersVersion.setFunctionCode(tenantFunctionComposite.getTenantFunctionMain().getFunctionCode());
            }
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getCreateBy())){
                tenantFunctionParametersVersion.setCreateBy(SecurityContextHolder.getUserName());
            }
            tenantFunctionParametersVersion.setUpdateBy(SecurityContextHolder.getUserName());
            tenantFunctionParametersVersion.setUpdateTime(DateUtils.getNowDate());
        }
    }

    /**
     * 校验更新租户功能点参数信息
     * @param tenantFunctionParametersVersions
     * @param tenantFunctionComposite
     */
    private void verifyUpdateTenantFunctionParametersVersion(List<TenantFunctionParametersVersion> tenantFunctionParametersVersions, TenantFunctionComposite tenantFunctionComposite) {
        int index=0;
        for(TenantFunctionParametersVersion tenantFunctionParametersVersion:tenantFunctionParametersVersions){
            if(tenantFunctionParametersVersion==null)
                throw new RuntimeException("租户组件功能点参数版本表不能为空");
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getParameterName()))
                throw new RuntimeException("租户组件功能点参数版本表参数名称不能为空");
            //tenantFunctionParametersVersions列表中参数名称不能重复
            if(isRepeatParameterName(tenantFunctionParametersVersions,tenantFunctionParametersVersion,index))
                throw new RuntimeException("租户组件功能点参数版本表参数名称："+tenantFunctionParametersVersion.getParameterName()+"不能重复");


            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getParameterType()))
                throw new RuntimeException("租户组件功能点参数版本表参数类型不能为空");
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getParameterCode())){
                tenantFunctionParametersVersion.setParameterCode(getNewParameterCode());
            }
            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getEnterpriseCode())){
                tenantFunctionParametersVersion.setEnterpriseCode(tenantFunctionComposite.getTenantFunctionMain().getEnterpriseCode());
            }

            if(StringUtils.isEmpty(tenantFunctionParametersVersion.getIsCurrent())){
                tenantFunctionParametersVersion.setIsCurrent(tenantFunctionComposite.getTenantFunctionVersion().getIsCurrent());
            }

            if(!IBusinessConstant.SYSTEM_YES.equals(tenantFunctionParametersVersion.getIsCurrent()) &&
                    !IBusinessConstant.SYSTEM_NO.equals(tenantFunctionParametersVersion.getIsCurrent())
                )
                tenantFunctionParametersVersion.setIsCurrent(tenantFunctionComposite.getTenantFunctionVersion().getIsCurrent());
            index++;
        }
    }

    /**
     * 判断参数名称是否重复
     * @param tenantFunctionParametersVersions
     * @param tenantFunctionParametersVersion
     * @param index
     * @return
     */
    private boolean isRepeatParameterName(List<TenantFunctionParametersVersion> tenantFunctionParametersVersions, TenantFunctionParametersVersion tenantFunctionParametersVersion, int index) {
        for(int i=0;i<tenantFunctionParametersVersions.size();i++){
            if(i==index)
                continue;
            if(tenantFunctionParametersVersions.get(i).getParameterName().equals(tenantFunctionParametersVersion.getParameterName()))
                return true;
        }
        return false;
    }

    /**
     * 校验更新租户功能点版本信息
     * @param tenantFunctionVersion
     */
    private void verifyUpdateTenantFunctionVersion(TenantFunctionVersion tenantFunctionVersion) {
        if(tenantFunctionVersion==null)
            throw new RuntimeException("租户组件功能点版本表不能为空");
        if(StringUtils.isEmpty(tenantFunctionVersion.getDesignScript()))
            throw new RuntimeException("租户组件功能点版本表设计脚本不能为空");
        if(StringUtils.isEmpty(tenantFunctionVersion.getIsReturnvalue()))
            throw new RuntimeException("租户组件功能点版本表是否返回值不能为空");
        if(!IBusinessConstant.SYSTEM_YES.equals(tenantFunctionVersion.getIsReturnvalue()) &&
                !IBusinessConstant.SYSTEM_NO.equals(tenantFunctionVersion.getIsReturnvalue())
            )
            throw new RuntimeException("租户组件功能点版本表是否返回值只能是Y或者N");
        if(IBusinessConstant.SYSTEM_YES.equals(tenantFunctionVersion.getIsReturnvalue()))
            if(StringUtils.isEmpty(tenantFunctionVersion.getReturnType()))
                throw new RuntimeException("租户组件功能点版本表返回值类型不能为空");
        if(StringUtils.isEmpty(tenantFunctionVersion.getCommitMessage()))
            throw new RuntimeException("租户组件功能点版本表提交信息不能为空");
//        if(StringUtils.isEmpty(tenantFunctionVersion.getEnterpriseCode()))
//            throw new RuntimeException("租户组件功能点版本表企业编码不能为空");

    }

    /**
     * 校验更新租户功能主信息
     * @param tenantFunctionMain
     */
    private void verifyUpdateTenantFunctionMain(TenantFunctionMain tenantFunctionMain) {
        if(tenantFunctionMain==null)
            throw new RuntimeException("租户组件功能点主表不能为空");
        if(StringUtils.isEmpty(tenantFunctionMain.getFunctionName()))
            throw new RuntimeException("租户组件功能点主表功能点名称不能为空");
        if(StringUtils.isEmpty(tenantFunctionMain.getClassName()))
            throw new RuntimeException("租户组件功能点主表类名不能为空");
        if(StringUtils.isEmpty(tenantFunctionMain.getFunctionCode()))
            throw new RuntimeException("租户组件功能点主表功能点编码不能为空");
        if(StringUtils.isEmpty(tenantFunctionMain.getEnterpriseCode()))
            throw new RuntimeException("租户组件功能点主表企业编码不能为空");
        if(StringUtils.isEmpty(tenantFunctionMain.getStatus()))
            throw new RuntimeException("租户组件功能点主表状态不能为空");

        if(tenantFunctionMain.getVersion()==0)
            throw new RuntimeException("租户组件功能点主表版本号不能为空");
        if(tenantFunctionMain.getFunctionId()==0)
            throw new RuntimeException("租户组件功能点主表功能点ID不能为空");
//        if(tenantFunctionMain.getSortNumber()==0)
//            throw new RuntimeException("租户组件功能点主表排序号不能为空");


    }
    /**
     * 验证所有节点之间至少存在一条有效连线
     *
     * @param elements    所有组件节点和菱形节点列表，每个节点应包含 "id" 字段
     * @param connections 所有连线列表，每个连线应包含 "startElementId" 和 "endElementId"
     * @return 一个包含是否有效和错误消息的数组，第一个元素是布尔值，第二个是错误消息
     */
    public  Object[] validateConnectionsExist(List<Map<String, String>> elements, List<Map<String, String>> connections) {
        // 收集所有节点的ID
        Set<String> nodeIds = new HashSet<>();
        for (Map<String, String> elem : elements) {
            nodeIds.add(elem.get("id"));
        }

        // 如果没有节点，直接返回有效
        if (nodeIds.isEmpty()) {
            return new Object[]{true, "设计为空"};
        }

        // 构建连接关系图
        Map<String, Set<String>> graph = new HashMap<>();
        for (String nodeId : nodeIds) {
            graph.put(nodeId, new HashSet<>());
        }

        for (Map<String, String> conn : connections) {
            String start = conn.get("startElementId");
            String end = conn.get("endElementId");
            if (nodeIds.contains(start) && nodeIds.contains(end)) {
                graph.get(start).add(end);
            }
        }

        // 检查是否所有节点都连通
        Set<String> visited = new HashSet<>();
        Queue<String> queue = new LinkedList<>();
        queue.add(nodeIds.iterator().next());  // 从任意节点开始

        while (!queue.isEmpty()) {
            String node = queue.poll();
            if (!visited.contains(node)) {
                visited.add(node);
                for (String neighbor : graph.get(node)) {
                    if (!visited.contains(neighbor)) {
                        queue.add(neighbor);
                    }
                }
            }
        }

        if (visited.size() != nodeIds.size()) {
            Set<String> missingNodes = new HashSet<>(nodeIds);
            missingNodes.removeAll(visited);
            return new Object[]{false, "存在孤立的节点: " + missingNodes};
        }

        return new Object[]{true, "所有节点都连通"};
    }
    /**
     * 验证每条连线都有有效的开始和结束节点
     *
     * @param connections 所有连线列表，每个连线应包含 "startElementId" 和 "endElementId"
     * @return 一个包含是否有效和错误消息的数组，第一个元素是 Boolean，第二个是 String 错误信息
     */
    public  Object[] validateConnectionEndpoints(List<Map<String, String>> connections) {
        List<String> invalidConnections = new ArrayList<>();

        for (int i = 0; i < connections.size(); i++) {
            Map<String, String> conn = connections.get(i);
            String start = conn.get("startElementId");
            String end = conn.get("endElementId");

            if (start == null || start.isEmpty() || end == null || end.isEmpty()) {
                invalidConnections.add(String.valueOf(i + 1));
            }
        }

        if (!invalidConnections.isEmpty()) {
            return new Object[]{
                    false,
                    "以下连线缺少开始或结束节点: " + String.join(", ", invalidConnections)
            };
        }

        return new Object[]{true, "所有连线都有有效的开始和结束节点"};
    }
    /**
     * 检测图中是否存在死循环
     *
     * @param elements    所有组件节点和菱形节点列表，每个节点应包含 "id" 字段
     * @param connections 所有连线列表，每个连线应包含 "startElementId" 和 "endElementId"
     * @return 一个包含是否有效和错误消息的数组，第一个元素是 Boolean，第二个是 String 错误信息
     */
    public  Object[] detectDeadLoops(List<Map<String, String>> elements, List<Map<String, String>> connections) {
        // 构建节点集合
        Set<String> nodeIds = new HashSet<>();
        for (Map<String, String> elem : elements) {
            nodeIds.add(elem.get("id"));
        }

        if (nodeIds.isEmpty()) {
            return new Object[]{true, "设计为空"};
        }

        // 构建有向图
        Map<String, List<String>> graph = new HashMap<>();
        for (String nodeId : nodeIds) {
            graph.put(nodeId, new ArrayList<>());
        }

        for (Map<String, String> conn : connections) {
            String start = conn.get("startElementId");
            String end = conn.get("endElementId");
            if (nodeIds.contains(start) && nodeIds.contains(end)) {
                graph.get(start).add(end);
            }
        }

        // 检测环
        Set<String> visited = new HashSet<>();
        Set<String> recursionStack = new HashSet<>();
        List<List<String>> cycles = new ArrayList<>();

        for (String node : nodeIds) {
            if (!visited.contains(node)) {
                dfs(node, new ArrayList<>(), visited, recursionStack, cycles, graph);
            }
        }

        if (!cycles.isEmpty()) {
            List<String> cycleDescriptions = new ArrayList<>();
            for (List<String> cycle : cycles) {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < cycle.size() - 1; i++) {
                    sb.append("节点").append(cycle.get(i)).append(" -> ");
                }
                sb.append("节点").append(cycle.get(cycle.size() - 1));
                cycleDescriptions.add(sb.toString());
            }
            return new Object[]{
                    false,
                    "检测到死循环: " + String.join("; ", cycleDescriptions)
            };
        }

        return new Object[]{true, "没有检测到死循环"};
    }

    private  void dfs(String node, List<String> path, Set<String> visited,
                            Set<String> recursionStack, List<List<String>> cycles,
                            Map<String, List<String>> graph) {
        visited.add(node);
        recursionStack.add(node);
        path.add(node);

        for (String neighbor : graph.getOrDefault(node, Collections.emptyList())) {
            if (recursionStack.contains(neighbor)) {
                int cycleStart = path.indexOf(neighbor);
                List<String> cycle = new ArrayList<>(path.subList(cycleStart, path.size()));
                cycle.add(neighbor); // 确保闭环显示
                cycles.add(cycle);
            } else if (!visited.contains(neighbor)) {
                dfs(neighbor, path, visited, recursionStack, cycles, graph);
            }
        }

        recursionStack.remove(node);
        path.remove(path.size() - 1);
    }
}
